/* Copyright (C) 2005-2013, Unigine Corp. All rights reserved.
 *
 * File:    vertex_base_deferred.h
 * Desc:    Base deferred shader
 * Version: 1.02
 * Author:  Alexander Zapryagaev <frustum@unigine.com>
 *
 * This file is part of the Unigine engine (http://unigine.com/).
 *
 * Your use and or redistribution of this software in source and / or
 * binary form, with or without modification, is subject to: (i) your
 * ongoing acceptance of and compliance with the terms and conditions of
 * the Unigine License Agreement; and (ii) your inclusion of this notice
 * in any version of this software that you use or redistribute.
 * A copy of the Unigine License Agreement is available by contacting
 * Unigine Corp. at http://unigine.com/
 */

/******************************************************************************\
*
* OpenGL
*
\******************************************************************************/

#ifdef OPENGL
	
	#ifndef VERTEX_BASE_DEFERRED
		#define VERTEX_BASE_DEFERRED
		
		#ifdef USE_PARALLAX && PARALLAX
			uniform float parallax_scale;
		#endif
		
	#else
		
		gl_Position = getPosition(vertex);
		
		s_texcoord_0 = texcoord;
		
		#ifdef USE_TESSELLATION && TESSELLATION
			
			#ifdef USE_ALPHA_FADE && ALPHA_FADE
				gl_Position.w = getAlphaFade(bound_sphere);
			#endif
			
			#ifdef USE_DEFERRED || USE_OCCLUSION
				s_texcoord_1.xyz = float3(tangent.x,binormal.x,normal.x);
				s_texcoord_2.xyz = float3(tangent.y,binormal.y,normal.y);
				s_texcoord_3.xyz = float3(tangent.z,binormal.z,normal.z);
			#endif
			
			#ifdef PATCH
				s_texcoord_6.xy = patch_parameters;
			#endif
			
		#else
			
			s_texcoord_1.xyz = vertex.xyz * DepthRange.w;
			
			#ifdef USE_DEFERRED || USE_OCCLUSION
				s_texcoord_2.xyz = float3(tangent.x,binormal.x,normal.x);
				s_texcoord_3.xyz = float3(tangent.y,binormal.y,normal.y);
				s_texcoord_4.xyz = float3(tangent.z,binormal.z,normal.z);
			#endif
			
			#ifdef USE_PARALLAX && PARALLAX
				float3 camera_direction = -vertex.xyz;
				s_texcoord_5.x = dot(camera_direction,tangent);
				s_texcoord_5.y = dot(camera_direction,binormal);
				s_texcoord_5.z = dot(camera_direction,normal);
				
				float aspect = s_material_textures[10].x * s_material_textures[10].w;
				if(aspect > 1.0f) s_texcoord_6.xy = float2(parallax_scale / aspect,parallax_scale);
				else s_texcoord_6.xy = float2(parallax_scale,parallax_scale * aspect);
			#endif
			
			#ifdef TRIPLANAR
				s_texcoord_0.xy = direction.xy;
				s_texcoord_6.xyz = position.xyz;
				s_texcoord_6.w = direction.z;
			#endif
			
			#ifdef OVERLAP
				#ifdef GLOBAL
					s_texcoord_6.xyz = mul4(s_imodelview,vertex).xyz;
					s_texcoord_6.w = mul3(s_imodelview,normal).z;
				#else
					s_texcoord_6.xyz = position.xyz;
					s_texcoord_6.w = direction.z;
				#endif
			#endif
			
			#ifdef PATCH
				s_texcoord_6.xy = patch_parameters;
			#endif
			
			#ifdef USE_ALPHA_FADE && ALPHA_FADE
				s_texcoord_9.x = getAlphaFade(bound_sphere);
			#endif
			
		#endif
		
	#endif
	
/******************************************************************************\
*
* Direct3D11
*
\******************************************************************************/

#elif DIRECT3D11
	
	#ifndef VERTEX_BASE_DEFERRED
		#define VERTEX_BASE_DEFERRED
		
		struct VERTEX_OUT {
			float4 position : OUT_POSITION;
			float4 texcoord_0 : TEXCOORD0;
			#ifdef USE_TESSELLATION && TESSELLATION
				#ifdef USE_DEFERRED || USE_OCCLUSION
					float3 texcoord_1 : TEXCOORD1;
					float3 texcoord_2 : TEXCOORD2;
					float3 texcoord_3 : TEXCOORD3;
				#endif
				float4 texcoord_9 : TEXCOORD9;
			#else
				float3 texcoord_1 : TEXCOORD1;
				#ifdef USE_DEFERRED || USE_OCCLUSION
					float3 texcoord_2 : TEXCOORD2;
					float3 texcoord_3 : TEXCOORD3;
					float3 texcoord_4 : TEXCOORD4;
				#endif
				#ifdef USE_PARALLAX && PARALLAX
					float3 texcoord_5 : TEXCOORD5;
					float2 texcoord_6 : TEXCOORD6;
				#endif
				#ifdef TRIPLANAR || OVERLAP
					float4 texcoord_6 : TEXCOORD6;
				#endif
				#ifdef PATCH
					float2 texcoord_6 : TEXCOORD6;
				#endif
				#ifdef USE_ALPHA_FADE && ALPHA_FADE
					float1 texcoord_9 : TEXCOORD9;
				#endif
			#endif
		};
		
		#ifdef USE_PARALLAX && PARALLAX
			cbuffer shader_deferred_parameters {
				float parallax_scale;
			};
		#endif
		
	#else
		
		OUT.position = getPosition(vertex);
		
		OUT.texcoord_0 = texcoord;
		
		#ifdef USE_TESSELLATION && TESSELLATION
			
			#ifdef USE_ALPHA_FADE && ALPHA_FADE
				OUT.position.w = getAlphaFade(bound_sphere);
			#endif
			
			#ifdef USE_DEFERRED || USE_OCCLUSION
				OUT.texcoord_1 = float3(tangent.x,binormal.x,normal.x);
				OUT.texcoord_2 = float3(tangent.y,binormal.y,normal.y);
				OUT.texcoord_3 = float3(tangent.z,binormal.z,normal.z);
			#endif
			
			#ifdef PATCH
				OUT.texcoord_6 = patch_parameters;
			#endif
			
		#else
			
			OUT.texcoord_1 = vertex.xyz * DepthRange.w;
			
			#ifdef USE_DEFERRED || USE_OCCLUSION
				OUT.texcoord_2 = float3(tangent.x,binormal.x,normal.x);
				OUT.texcoord_3 = float3(tangent.y,binormal.y,normal.y);
				OUT.texcoord_4 = float3(tangent.z,binormal.z,normal.z);
			#endif
			
			#ifdef USE_PARALLAX && PARALLAX
				float3 camera_direction = -vertex.xyz;
				OUT.texcoord_5.x = dot(camera_direction,tangent);
				OUT.texcoord_5.y = dot(camera_direction,binormal);
				OUT.texcoord_5.z = dot(camera_direction,normal);
				
				float aspect = s_material_textures[10].x * s_material_textures[10].w;
				if(aspect > 1.0f) OUT.texcoord_6 = float2(parallax_scale / aspect,parallax_scale);
				else OUT.texcoord_6 = float2(parallax_scale,parallax_scale * aspect);
			#endif
			
			#ifdef TRIPLANAR
				OUT.texcoord_0.xy = direction.xy;
				OUT.texcoord_6.xyz = position.xyz;
				OUT.texcoord_6.w = direction.z;
			#endif
			
			#ifdef OVERLAP
				#ifdef GLOBAL
					OUT.texcoord_6.xyz = mul4(s_imodelview,vertex).xyz;
					OUT.texcoord_6.w = mul3(s_imodelview,normal).z;
				#else
					OUT.texcoord_6.xyz = position.xyz;
					OUT.texcoord_6.w = direction.z;
				#endif
			#endif
			
			#ifdef PATCH
				OUT.texcoord_6 = patch_parameters;
			#endif
			
			#ifdef USE_ALPHA_FADE && ALPHA_FADE
				OUT.texcoord_9.x = getAlphaFade(bound_sphere);
			#endif
			
		#endif
		
	#endif
	
/******************************************************************************\
*
* Direct3D9
*
\******************************************************************************/

#elif DIRECT3D9
	
	#ifndef VERTEX_BASE_DEFERRED
		#define VERTEX_BASE_DEFERRED
		
		struct VERTEX_OUT {
			float4 position : POSITION;
			float4 texcoord_0 : TEXCOORD0;
			float3 texcoord_1 : TEXCOORD1;
			#ifdef USE_DEFERRED || USE_OCCLUSION
				float3 texcoord_2 : TEXCOORD2;
				float3 texcoord_3 : TEXCOORD3;
				float3 texcoord_4 : TEXCOORD4;
			#endif
			#ifdef USE_PARALLAX && PARALLAX
				float3 texcoord_5 : TEXCOORD5;
				float2 texcoord_6 : TEXCOORD6;
			#endif
			#ifdef TRIPLANAR || OVERLAP
				float4 texcoord_6 : TEXCOORD6;
			#endif
			#ifdef PATCH
				float2 texcoord_6 : TEXCOORD6;
			#endif
			#ifdef USE_ALPHA_FADE && ALPHA_FADE
				float4 texcoord_7 : TEXCOORD7;
			#endif
		};
		
		#ifdef USE_PARALLAX && PARALLAX
			float parallax_scale;
		#endif
		
	#else
		
		OUT.position = getPosition(vertex);
		
		OUT.texcoord_0 = texcoord;
		
		OUT.texcoord_1 = vertex.xyz * DepthRange.w;
		
		#ifdef USE_DEFERRED || USE_OCCLUSION
			OUT.texcoord_2 = float3(tangent.x,binormal.x,normal.x);
			OUT.texcoord_3 = float3(tangent.y,binormal.y,normal.y);
			OUT.texcoord_4 = float3(tangent.z,binormal.z,normal.z);
		#endif
		
		#ifdef USE_PARALLAX && PARALLAX
			float3 camera_direction = -vertex.xyz;
			OUT.texcoord_5.x = dot(camera_direction,tangent);
			OUT.texcoord_5.y = dot(camera_direction,binormal);
			OUT.texcoord_5.z = dot(camera_direction,normal);
			
			float aspect = s_material_textures[10].x * s_material_textures[10].w;
			if(aspect > 1.0f) OUT.texcoord_6 = float2(parallax_scale / aspect,parallax_scale);
			else OUT.texcoord_6 = float2(parallax_scale,parallax_scale * aspect);
		#endif
		
		#ifdef TRIPLANAR
			OUT.texcoord_0.xy = direction.xy;
			OUT.texcoord_6.xyz = position.xyz;
			OUT.texcoord_6.w = direction.z;
		#endif
		
		#ifdef OVERLAP
			#ifdef GLOBAL
				OUT.texcoord_6.xyz = mul4(s_imodelview,vertex).xyz;
				OUT.texcoord_6.w = mul3(s_imodelview,normal).z;
			#else
				OUT.texcoord_6.xyz = position.xyz;
				OUT.texcoord_6.w = direction.z;
			#endif
		#endif
		
		#ifdef PATCH
			OUT.texcoord_6 = patch_parameters;
		#endif
		
		#ifdef USE_ALPHA_FADE && ALPHA_FADE
			OUT.texcoord_7 = getProjection(OUT.position);
			OUT.texcoord_7.z = getAlphaFade(bound_sphere);
		#endif
		
	#endif
	
/******************************************************************************\
*
* PlayStation3
*
\******************************************************************************/

#elif PLAYSTATION3
	
	#ifndef VERTEX_BASE_DEFERRED
		#define VERTEX_BASE_DEFERRED
		
		struct VERTEX_OUT {
			float4 position : POSITION;
			float4 texcoord_0 : TEXCOORD0;
			float3 texcoord_1 : TEXCOORD1;
			#ifdef USE_DEFERRED || USE_OCCLUSION
				float3 texcoord_2 : TEXCOORD2;
				float3 texcoord_3 : TEXCOORD3;
				float3 texcoord_4 : TEXCOORD4;
			#endif
			#ifdef USE_PARALLAX && PARALLAX
				float3 texcoord_5 : TEXCOORD5;
				float2 texcoord_6 : TEXCOORD6;
			#endif
			#ifdef TRIPLANAR || OVERLAP
				float4 texcoord_8 : TEXCOORD8;
			#endif
			#ifdef PATCH
				float2 texcoord_8 : TEXCOORD8;
			#endif
			#ifdef USE_ALPHA_FADE && ALPHA_FADE
				float4 texcoord_9 : TEXCOORD9;
			#endif
		};
		
		#ifdef USE_PARALLAX && PARALLAX
			uniform float parallax_scale;
		#endif
		
	#else
		
		OUT.position = getPosition(vertex);
		
		OUT.texcoord_0 = texcoord;
		
		OUT.texcoord_1 = vertex.xyz * DepthRange.w;
		
		#ifdef USE_DEFERRED || USE_OCCLUSION
			OUT.texcoord_2 = float3(tangent.x,binormal.x,normal.x);
			OUT.texcoord_3 = float3(tangent.y,binormal.y,normal.y);
			OUT.texcoord_4 = float3(tangent.z,binormal.z,normal.z);
		#endif
		
		#ifdef USE_PARALLAX && PARALLAX
			float3 camera_direction = -vertex.xyz;
			OUT.texcoord_5.x = dot(camera_direction,tangent);
			OUT.texcoord_5.y = dot(camera_direction,binormal);
			OUT.texcoord_5.z = dot(camera_direction,normal);
			
			float aspect = s_material_textures[10].x * s_material_textures[10].w;
			if(aspect > 1.0f) OUT.texcoord_6 = float2(parallax_scale / aspect,parallax_scale);
			else OUT.texcoord_6 = float2(parallax_scale,parallax_scale * aspect);
		#endif
		
		#ifdef TRIPLANAR
			OUT.texcoord_0.xy = direction.xy;
			OUT.texcoord_8.xyz = position.xyz;
			OUT.texcoord_8.w = direction.z;
		#endif
		
		#ifdef OVERLAP
			#ifdef GLOBAL
				OUT.texcoord_8.xyz = mul4(s_imodelview,vertex).xyz;
				OUT.texcoord_8.w = mul3(s_imodelview,normal).z;
			#else
				OUT.texcoord_8.xyz = position.xyz;
				OUT.texcoord_8.w = direction.z;
			#endif
		#endif
		
		#ifdef PATCH
			OUT.texcoord_8 = patch_parameters;
		#endif
		
		#ifdef USE_ALPHA_FADE && ALPHA_FADE
			OUT.texcoord_9 = getProjection(OUT.position);
			OUT.texcoord_9.z = getAlphaFade(bound_sphere);
		#endif
		
	#endif
	
#endif
